/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package FrameWork.Objects.Chacracter.Enemy;


import FrameWork.GameScreen;
import FrameWork.Objects.Character.MyCharacter;
import FrameWork.Objects.MyObject;
import FrameWork.Point;
import FrameWork.RSFont;
import FrameWork.RSMainGame;
import GamePlay.Global;
import java.io.IOException;
import java.util.Vector ;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.Sprite;
/**
 *
 * @author ThanhTri
*/

public class Friend  extends MyCharacter{
    protected int m_FrameFire;
    protected int m_XFire;
    protected float m_SaveTimeFire;
          
//    Fire m_Fire;
    public Friend(int _X,int _Y, int _SizeX, int _SizeY, 
            float _TimeAni, float _TimeSpeed,int _Direct,
            int _Map[][],int _Width, int _Height, int _ID) throws IOException{    
         super(_X,_Y,_SizeX,_SizeY, _TimeAni, _TimeSpeed,_Direct,_Map,_Width,_Height, _ID);
         m_STATUS = Global.STT_ACTIVE;
         m_CurFrame = 24;
         m_FrameFire = 0;
         m_SaveTimeFire = 0;
         m_XFire = m_Ran.nextInt(10); 
//         m_Fire = new Fire(_X, _Y, 30, 30, 0.2f, _Map, _Width, _Height, Global.ID_FIRE);
     }

    public void UpdateAnimation (float _Time){
       
        m_SaveTimeAni += _Time;
        if (m_SaveTimeAni>= m_TimeAni){
            m_SaveTimeAni = 0;
            
            switch (m_CurDirect)
            {
            case Global.DIR_UP: 
                m_CurFrame= (m_CurFrame + 1)%3 + 21;
                break;
            case Global.DIR_DOWN: 
                m_CurFrame= (m_CurFrame+1)%3 + 12;
                break;
            case Global.DIR_LEFT:
                m_CurFrame= (m_CurFrame+1)%3 + 15;
                break;
            case Global.DIR_RIGHT: 
                m_CurFrame= (m_CurFrame+1)%3 + 18;
                break;
            }        
        }
        
    }
    
    public void Update(float _Time,int _Terrain[][]) {
        super.Update(_Time,_Terrain);
         m_SaveTimeFire+= _Time;
        if(m_SaveTimeFire>=0.2f){
            m_SaveTimeFire-=0.2f;
            m_FrameFire =(++ m_FrameFire)%7;
        }
        
        switch(m_STATUS){
            case Global.STT_INVI:
                m_TimeUpdate+=_Time;
                if(m_TimeUpdate>=1.0f){
                    m_TimeUpdate = 0;
                    m_STATUS= Global.STT_NONE;
                    m_OldStatus = Global.STT_NONE;
                }
                break;
        }
    }
    public void UpdateAI (float _Time,
              MyCharacter _Obj, Vector _Enemy,int _Terrain[][]){
        AutoGO(_Time, _Terrain);
    }
      public void ActionCollision (MyObject _Object){
        if ( _Object.getSTATUS()== Global.STT_DEATH)return;
        switch (_Object.getID()){
            
            //<editor-fold defaultstate="collased" desc="Boom">
            case Global.ID_BOOM_EXPLOSION:
                if(m_STATUS != Global.STT_INVI & m_STATUS != Global.STT_NONE){
                    m_STATUS = Global.STT_INVI;
                    m_OldStatus = Global.STT_INVI;
                }
                break;
            case Global.ID_FIRE:
                if(m_STATUS == Global.STT_NONE){
                    m_STATUS = Global.STT_ACTIVE;
                }
                break;
//            case Global.ID_HOUSE:
//            case Global.ID_FRIEND:
//            case Global.ID_PIG:
            case Global.ID_CHICKEN:
//            case Global.ID_PIGAI:
            case Global.ID_CHICKENAI:
                if(m_STATUS == Global.STT_NONE && 
                    _Object.getSTATUS() == Global.STT_ACTIVE){
                    m_STATUS = Global.STT_ACTIVE;
                }
                break;
            default:
                //</editor-fold>
        }
    }
    public void DrawScreen(Graphics _Graphics, GameScreen _Screen) {
        switch(m_STATUS){
            case Global.STT_NONE:
                super.DrawScreen(_Graphics, _Screen);
                break;
            case Global.STT_ACTIVE:
                super.DrawScreen(_Graphics, _Screen);
                if (m_Ran.nextInt(3)!=0){
                    Sprite Fire = RSMainGame.getRS().getFire();
                    Fire.setFrame(m_FrameFire);
                    Fire.setPosition((int)m_CurX +m_XFire - (_Screen.getXView() - _Screen.getWidth()/2), 
                    (int)m_CurY - 10 - (_Screen.getYView() - _Screen.getHeight()/2));
                    Fire.paint(_Graphics);
                }
                if(System.currentTimeMillis()%600 <=400){
                    
                    RSFont.getRS().getFont(Global.FONT_SMALL).DrawString(
                        "HELP",(int)m_CurX - (_Screen.getXView() - _Screen.getWidth()/2)
                        ,(int)m_CurY-10 - (_Screen.getYView() - _Screen.getHeight()/2), _Graphics);
                }
                break;
            case Global.STT_INVI:
//                if (m_Ran.nextInt(2)==0){
                   super.DrawScreen(_Graphics, _Screen);
                   RSFont.getRS().getFont(Global.FONT_SMALL).DrawString(
                        "THANK YOU",(int)m_CurX - 10 - (_Screen.getXView() - _Screen.getWidth()/2)
                        ,(int)m_CurY-10 - (_Screen.getYView() - _Screen.getHeight()/2), _Graphics);
//                }
                break;
        }
    }
     public void AutoGO (float _Time,int _Terrain[][]) {
        if(!m_iRun){
            
            int _Reverse_Dir = ReverseDirect();
           Vector _Vector_Dir = new Vector ();
           
           for (int i = 1; i < 4; i++){
               _Vector_Dir.addElement(
                       new Integer((i+_Reverse_Dir)%4));
           }
           
           int rand = m_Ran.nextInt(3);
            
            
            for (int i = 0; i < rand; i++) {
                Integer iter = (Integer) _Vector_Dir.firstElement();
                _Vector_Dir.addElement(iter);
                _Vector_Dir.removeElementAt(0);                
            }
            
            _Vector_Dir.addElement(new Integer (_Reverse_Dir));
            
            for (int i = 0; i < _Vector_Dir.size();i ++) {
                Integer tdir = (Integer)_Vector_Dir.elementAt(i);
                int dir = tdir.intValue();
                m_NextX = m_X;
                m_NextY = m_Y;
                FindNextStep(m_X, m_Y, dir);
                
                 if(m_X!=m_NextX || m_Y!= m_NextY){
                     if(_Terrain[m_NextX][m_NextY]!=Global.ID_GRASS &&
                         _Terrain[m_NextX][m_NextY]!=Global.ID_BOOM &&
                         _Terrain[m_NextX][m_NextY]!=Global.ID_HOUSE &&
                         _Terrain[m_NextX][m_NextY]!=Global.ID_DOOR){
                        m_CurDirect = dir;
                        m_Direct = dir;
                        m_iRun = true;
                        break;
                     }   
                 }               
            }       
        }else{
            MoveLayout(_Time);
        }
     }
     
     public void AutoFollow (float _Time,MyCharacter _Man,int _Terrain[][]){
         int Man_X = _Man.getX();
         int Man_Y = _Man.getY();
         if (m_X ==Man_X && m_Y ==Man_Y  ) {
             AutoGO(_Time,_Terrain);
         }
        int disX=Math.abs(m_X-Man_X);
	int disY=Math.abs(m_Y-Man_Y);
	if(disX>10||disY>10)
	{
            AutoGO(_Time,_Terrain);
            return;
	}
        
        // Find direct
        int[] Dir = new int[4];
        
        //<editor-fold defaultstate="collapsed" desc="Random chose director ">
        if (m_Ran.nextInt(2)==0) {
            Dir[0] = Global.DIR_UP;
            Dir[1] = Global.DIR_LEFT;
            Dir[2] = Global.DIR_DOWN;
            Dir[3] = Global.DIR_RIGHT;
            if (m_Y> Man_Y) {
                if (m_X < Man_X) {
                    Dir[1] = Global.DIR_RIGHT;
                    Dir[3] = Global.DIR_LEFT;
                }
            }else if (m_Y < Man_Y) {
                Dir[0] = Global.DIR_DOWN;
                Dir[2] = Global.DIR_UP;
                if (m_X < Man_X) {
                    Dir[1] = Global.DIR_RIGHT;
                    Dir[3] = Global.DIR_LEFT;
                }
            }else {
                
                Dir[0] = Global.DIR_LEFT;
                Dir[1] = Global.DIR_UP;
                Dir[2] = Global.DIR_RIGHT;
                Dir[3] = Global.DIR_DOWN;
                if (m_X < Man_X) {
                    Dir[0] = Global.DIR_RIGHT;
                    Dir[2] = Global.DIR_LEFT;
                }
            }
            
            
        }else{
            Dir[0] = Global.DIR_LEFT;
            Dir[1] = Global.DIR_UP;
            Dir[2] = Global.DIR_RIGHT;
            Dir[3] = Global.DIR_DOWN;
            
            if (m_X> Man_X) {
                if (m_Y < Man_Y) {
                    Dir[1] = Global.DIR_DOWN;
                    Dir[3] = Global.DIR_UP;
                }
            }else if (m_Y < Man_Y) {
                Dir[0] = Global.DIR_RIGHT;
                Dir[2] = Global.DIR_LEFT;
                if (m_X < Man_X) {
                    Dir[1] = Global.DIR_DOWN;
                    Dir[3] = Global.DIR_UP;
                }
            }else {
                
                Dir[0] = Global.DIR_UP;
                Dir[1] = Global.DIR_LEFT;
                Dir[2] = Global.DIR_DOWN;
                Dir[3] = Global.DIR_RIGHT;
                if (m_Y < Man_Y) {
                    Dir[0] = Global.DIR_DOWN;
                    Dir[2] = Global.DIR_UP;
                }
            }
            //</editor-fold>
            
        }
         if (!m_iRun) {
             for (int i = 0; i < 4; i++) {
                int dir = Dir[i];
                m_NextX = m_X;
                m_NextY = m_Y;
                FindNextStep(m_X, m_Y, dir);
                 if(m_X!=m_NextX || m_Y!= m_NextY){
                    
                     if(_Terrain[m_NextX][m_NextY]!=Global.ID_GRASS &&
                         _Terrain[m_NextX][m_NextY]!=Global.ID_BOOM &&
                         _Terrain[m_NextX][m_NextY]!=Global.ID_HOUSE &&
                         _Terrain[m_NextX][m_NextY]!=Global.ID_DOOR){
                         
                        m_CurDirect = dir;
                        m_Direct = dir;
                        m_iRun = true;
                        break;
                     }   
                 } 
             }
         } else {
             MoveLayout(_Time);
         }
     }
     
      public void AutoAI (float _Time,
              MyCharacter _Obj, Vector _Enemy,int _Terrain[][]) {
         if (!m_iRun){
             
             if (_Obj.getSTATUS()==Global.STT_ACTIVE ){
            
                //<editor-fold defaultstate="collapsed" desc="Astart to find path">
             Vector vPath = AStart(_Terrain,
                     m_WidthMap, m_HeightMap,
                     m_X, m_Y, _Obj.getX(), _Obj.getY(),_Enemy);
             
             
             if (vPath == null){
                 AutoGO(_Time,_Terrain);
             }else{
                 vPath.removeElementAt(0);
                 Point pNext = (Point) vPath.firstElement();            
                if(m_X!=pNext.X || m_Y!= pNext.Y){   

                    m_NextX = pNext.X;
                    m_NextY = pNext.Y;
                    
                    // <editor-fold defaultstate="collapsed" desc="Set Direction">
                    if (m_NextX > m_X){
                        m_Direct = Global.DIR_RIGHT;
                    }else if (m_NextX< m_X){
                        m_Direct = Global.DIR_LEFT;
                    }else if (m_NextY > m_Y){
                        m_Direct = Global.DIR_DOWN;
                    }else {
                        m_Direct = Global.DIR_UP;
                    }
                    // </editor-fold>
                    
                    m_CurDirect = m_Direct;
                    m_iRun = true;
                }                  
             }   
             //</editor-fold>
             
              }else{
                 AutoGO(_Time, _Terrain);
             }
             
         }else{         
            MoveLayout(_Time);
        }
     }
    
//     A* algorithms
     public Vector AStart (int _Map[][],
             int _Width,int _Height,
             int _StartX, int _StartY,
             int _EndX ,int _EndY,Vector _Enemy ) {
             
         Vector Queue = new Vector ();
         
         Point[][] pResult = new Point[_Width][_Height];
         for (int i = 0; i < _Width; i++) {
             for (int j = 0; j < _Height; j++) {
                 pResult[i][j] = new Point(-1,-1);
             }             
         }
         boolean[][] biCheck = new boolean[_Width][_Height];
         
         Point pCur, pStart,pEnd;
         pCur   = new Point();
         pStart = new Point(_StartX,_StartY);
         pEnd   = new Point(_EndX,_EndY);
         
        int di[] = {-1,0,1,0};
        int dj[] = {0,-1,0,1};
        
        biCheck[pStart.X][pStart.Y] = true;        
        Queue.addElement(pStart);
        
        while ( !Queue.isEmpty() ){
            pCur = (Point) Queue.firstElement();
            Queue.removeElementAt(0); // Pop queue
            
            for (int i = 0; i < 4; i++) {
                int tx = pCur.X + di[i];
                int ty = pCur.Y + dj[i];
                
                // Out sile map
                if ((tx < 0) || (tx>=_Width) 
                        || (ty < 0) || (ty >= _Height)) continue;
                // Checked
                if (biCheck[tx][ty]) continue;
                // Have brick
                if (_Map[tx][ty]== Global.ID_GRASS) continue;
                if (_Map[tx][ty]== Global.ID_BOOM) continue;
                if (_Map[tx][ty]== Global.ID_DOOR) continue;
                if (_Map[tx][ty]== Global.ID_HOUSE) continue;
                // have enemy
                boolean iTest = false;
                for (int iE = 0; iE < _Enemy.size();iE++){
                    Friend enemy =(Friend) _Enemy.elementAt(iE);
                    if (enemy.getX() == tx && enemy.getY() == ty){
                        iTest = true;
                        break;
                    }
                }
                if (iTest) continue;
                
                pResult[tx][ty] = pCur;
                biCheck[tx][ty] = true;
                
                Queue.addElement(new Point(tx, ty));
                
                if (tx == _EndX && ty == _EndY){
                    Vector vResult = new Vector ();
                    
                    vResult.insertElementAt(new Point (_EndX,_EndY), 0);
                    Point pt = new Point (_EndX,_EndY);
                    
                    while((pt.X!= pStart.X)|| (pt.Y!= pStart.Y)){
                        Point pt1 = new Point ();
                        pt1.X = pResult[pt.X][pt.Y].X;
                        pt1.Y = pResult[pt.X][pt.Y].Y;
                        vResult.insertElementAt(new Point (pt1.X,pt1.Y), 0);
                        pt.X=pt1.X;
                        pt.Y=pt1.Y;
                    }
                    return vResult;
                }               
            }       
        }         
         return null;
     }
}
